// 
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

//!DESC RAVU-Lite (r2, compute)
//!HOOK LUMA
//!BIND HOOKED
//!BIND ravu_lite_lut2
//!WIDTH 2 HOOKED.w *
//!HEIGHT 2 HOOKED.h *
//!WHEN HOOKED.w OUTPUT.w / 0.833333 < HOOKED.h OUTPUT.h / 0.833333 < *
//!COMPUTE 64 16 32 8
shared float inp[340];
void hook() {
ivec2 group_base = ivec2(gl_WorkGroupID) * ivec2(gl_WorkGroupSize);
int local_pos = int(gl_LocalInvocationID.x) * 10 + int(gl_LocalInvocationID.y);
for (int id = int(gl_LocalInvocationIndex); id < 340; id += int(gl_WorkGroupSize.x * gl_WorkGroupSize.y)) {
int x = id / 10, y = id % 10;
inp[id] = HOOKED_tex(HOOKED_pt * vec2(float(group_base.x+x)+(-0.5), float(group_base.y+y)+(-0.5))).x;
}
barrier();
vec3 abd = vec3(0.0);
float gx, gy;
gx = (inp[local_pos + 10]-inp[local_pos + 0]);
gy = (inp[local_pos + 1]-inp[local_pos + 0]);
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.1018680644198163;
gx = (inp[local_pos + 11]-inp[local_pos + 1]);
gy = (inp[local_pos + 2]-inp[local_pos + 0])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.11543163961422666;
gx = (inp[local_pos + 12]-inp[local_pos + 2]);
gy = (inp[local_pos + 2]-inp[local_pos + 1]);
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.1018680644198163;
gx = (inp[local_pos + 20]-inp[local_pos + 0])/2.0;
gy = (inp[local_pos + 11]-inp[local_pos + 10]);
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.11543163961422666;
gx = (inp[local_pos + 21]-inp[local_pos + 1])/2.0;
gy = (inp[local_pos + 12]-inp[local_pos + 10])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.13080118386382833;
gx = (inp[local_pos + 22]-inp[local_pos + 2])/2.0;
gy = (inp[local_pos + 12]-inp[local_pos + 11]);
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.11543163961422666;
gx = (inp[local_pos + 20]-inp[local_pos + 10]);
gy = (inp[local_pos + 21]-inp[local_pos + 20]);
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.1018680644198163;
gx = (inp[local_pos + 21]-inp[local_pos + 11]);
gy = (inp[local_pos + 22]-inp[local_pos + 20])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.11543163961422666;
gx = (inp[local_pos + 22]-inp[local_pos + 12]);
gy = (inp[local_pos + 22]-inp[local_pos + 21]);
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.1018680644198163;
float a = abd.x, b = abd.y, d = abd.z;
float T = a + d, D = a * d - b * b;
float delta = sqrt(max(T * T / 4.0 - D, 0.0));
float L1 = T / 2.0 + delta, L2 = T / 2.0 - delta;
float sqrtL1 = sqrt(L1), sqrtL2 = sqrt(L2);
float theta = mix(mod(atan(L1 - a, b) + 3.141592653589793, 3.141592653589793), 0.0, abs(b) < 1.192092896e-7);
float lambda = sqrtL1;
float mu = mix((sqrtL1 - sqrtL2) / (sqrtL1 + sqrtL2), 0.0, sqrtL1 + sqrtL2 < 1.192092896e-7);
float angle = floor(theta * 24.0 / 3.141592653589793);
float strength = mix(mix(0.0, 1.0, lambda >= 0.004), mix(2.0, 3.0, lambda >= 0.05), lambda >= 0.016);
float coherence = mix(mix(0.0, 1.0, mu >= 0.25), 2.0, mu >= 0.5);
float coord_y = ((angle * 4.0 + strength) * 3.0 + coherence + 0.5) / 288.0;
vec4 res = vec4(0.0), w;
w = texture(ravu_lite_lut2, vec2(0.1, coord_y));
res += inp[local_pos + 0] * w + inp[local_pos + 22] * w.wzyx;
w = texture(ravu_lite_lut2, vec2(0.3, coord_y));
res += inp[local_pos + 1] * w + inp[local_pos + 21] * w.wzyx;
w = texture(ravu_lite_lut2, vec2(0.5, coord_y));
res += inp[local_pos + 2] * w + inp[local_pos + 20] * w.wzyx;
w = texture(ravu_lite_lut2, vec2(0.7, coord_y));
res += inp[local_pos + 10] * w + inp[local_pos + 12] * w.wzyx;
w = texture(ravu_lite_lut2, vec2(0.9, coord_y));
res += inp[local_pos + 11] * w;
res = clamp(res, 0.0, 1.0);
imageStore(out_image, ivec2(gl_GlobalInvocationID) * 2 + ivec2(0, 0), vec4(res[0], 0.0, 0.0, 0.0));
imageStore(out_image, ivec2(gl_GlobalInvocationID) * 2 + ivec2(0, 1), vec4(res[1], 0.0, 0.0, 0.0));
imageStore(out_image, ivec2(gl_GlobalInvocationID) * 2 + ivec2(1, 0), vec4(res[2], 0.0, 0.0, 0.0));
imageStore(out_image, ivec2(gl_GlobalInvocationID) * 2 + ivec2(1, 1), vec4(res[3], 0.0, 0.0, 0.0));
}
//!TEXTURE ravu_lite_lut2
//!SIZE 5 288
//!FORMAT rgba16hf
//!FILTER NEAREST
8e28b7a155a28f990d2d092df4aff1af92a19628b39998a22c2d08b0272d0bb0533c533c533c533c602762a005a4c91d972da52d41b03bb0c29fa527ef1c5da4222e70b0f22d7cb0513c523c523c513c3526029fefa34821ad2dd12d53b03eb0b8150328711a46a6492f8ab0432e0ab14e3c4e3c4e3c4e3c5628eba133a55221502e302e8db090b0a4a1a7288820aaa5f02ec8b0a32eddb04e3c503c503c4e3cbc26fea044a581246f2e3c2e9ab08eb07d99a6289d20aca7e12feeb0e62e50b14b3c503c503c4b3cbd242ba405a14026262ee22d72b063b0611ed029f39698a84c304db0782dbbb14a3c503c503c4a3c8e28379f2aa80f244a2ff82ef4b0e1b0259bac29792128a9a630a3b13530e3b1473c4d3c4d3c473cdf255c9840a74425a62e182ea3b07fb0d423592a9b93baaa2b3146b1972f55b2443c4f3c4f3c443c429c85a75a1de029a52d092d35b0f6af9f29fd2c2aa8f8ac3132b7ae002b68b3443c543c543c443c5328f819d9a961250f30642f5eb127b17f24742b3e1c72acc8310eb27f30dab2423c533c533c423c3a235021d5a61c24432fef2d08b178b08e2a802c59a74dad513264b06b2d28b3373c5e3c5e3c373c97ac3aadad2c952ea02d072b55b097ae36305331ccaf96b15f351527bfad9ab52a3c6d3c6d3c2a3c72284aa159a26d98fc2c0a2df2afe9afaca09328449be3a2732d1ab05c2d35b0543c523c523c543cd12726a024a46e1c322d6d2d2eb003b0509c81284c17c6a5b12e5db0a92db3b0503c533c533c503cfb2190a5f4966926c42c1f2df5afa3afca27922ba6a6c1aaae30d2afed2c13b24c3c523c523c4c3c05289fa26ba4f521652e1d2e99b086b0c6a127296f1f44a63d2fc2b0692eebb04d3c513c513c4d3c6c24b6a373a264269e2e142ea8b083b05618d229da19f2a86530a6b0052e9bb1473c533c533c473c1693dca7b11e9429bc2ee62da3b079b02024a32b91a275aa153191af372c6ab2453c543c543c453cc326eea069a66025bd2fb12e13b1d8b0389aa82aa41fd7a9033181b1ae2f06b2413c533c533c413c1010dba337a0d828532f9b2dd1b063b05b267f2c73a383ac42329ab06e2d04b3373c5c3c5c3c373c02a993aabc28c72cdd2eb12c9cb0f8af512b932e5caa6daed03394acaa1f4eb4333c623c623c333c4e21799f2da686288430be2ea9b1ffb03927052d9f9fbbade13265b1962e6db3313c643c643c313c84a76da2b023c029f82fd92a24b1eeaeee2c9b2fb9ab14b0a53417ad21a086b40b3c893c893c0b3cfcae4cacea2e4d2e4a2f689ff6b0cdaa3c2f7131f2ae6db10d372c2ce2b17bb6c43bb63cb63cc43b66289ea176a1b699f42c172d09b0d0af34a19928019858a36c2d1eb0302d19b0533c543c543c533c6b2727a2aaa13d1df12c612d2bb0b4afc40c61298f9c70a7e82e76b0c22dc0b0503c533c533c503c702189a6c91c3826c52d782d86b0e3af2821d22b04a57da9bc3033b05e2d0fb24a3c553c553c4a3c92271aa391a34622862e0a2ea1b084b021a26a29a81e7da6542fafb0242ee6b04b3c533c533c4b3c4c2175a40b9f7727032fed2dbfb086b0e3148b2a000454a9a33093b0982db2b1433c563c563c433c19a00fa8ab212d2a4f2fce2dc7b08db03b22152ccea2a1aa6c31aeafd72b85b23f3c5a3c5a3c3f3c0f2579a2d4a474261e30922e3ab1e1b0269e2e2b7b202eaa3c3167b10c2f09b23b3c583c583c3b3cb7a2a0a40016da291330352d03b15bb0a025072dd4a3e3acc43285b0772c21b32b3c663c663c2b3cc8a9a9a9d828b32c01306b2ce7b008b05929722e19a90aaefb337dada51e25b4243c6f3c6f3c243c6897cba141a373291331392e02b2f1b0a824522db91601ae593364b1862d60b3203c743c743c203c60aa5aa1db27572a9d30d92682b19fadbf2b1430f2a950b0443505ae83a87fb4c33bb13cb13cc33b49ae9da4c62d402b4a2f28ace2b0c01ebe2c483182ac3eb13137159e91b1b6b5593bec3cec3c593b832848a1d2a17f9b092d0c2d0bb0d4afc4a170282990ffa2522d16b02c2d11b0533c543c543c533c3527c1a2b5a04a1d402d892d50b0e1af549a162924893aa7db2e6eb0a32dadb0503c533c533c503cac22e5a57798a826092e532d9db0c7afb29d172c299b21aa063173b0452d0cb24b3c553c553c4b3c5e2769a3b8a23922a92efb2dabb084b01fa36729262076a64d2fa8b0f42dd2b04a3c543c543c4a3c0d1f3aa4039dab27732fcd2dcbb09bb0de9ae52aec8c35a9b0309fb0652d95b1403c593c593c403c8ea2cfa60621492a0330ba2de7b0b7b0c31c022ccca03aaa74311bb0152c52b23a3c5e3c5e3c3a3cd92300a3c6a304276830722e60b1f3b05aa2a42b6b2116aa58316db1a42eebb1353c5e3c5e3c353c98a517a4e11e182a9230e32c36b16fb0b622672d82a2f0ace832bfb0172cdab2213c6f3c6f3c213c0faa51a84e285f2c9030672c30b132b05f263b2e94a77badbc3320af182598b3193c783c783c193ca7a07fa233a1182abf31c72d56b206b13394662d7a24ecad9b338fb1dd2c20b3123c823c823c123c36ac36980b294f2a3331b622ccb120ada92814303fa64eb0843518b0c6a82fb4983bc53cc53c983bc3aded15b72c58296b2e2dacb2b07626932b1531a9aa3fb12737b1ac83b020b5353bfa3cfa3c353b922857a1a1a17b9c152d222d17b0ddafd6a27a287514eea2402d19b01d2dfbaf543c533c533c543c8127b8a28aa0c31a402d5b2d50b0b0afcca159291b1cdfa6f52e81b0a22da1b0513c523c523c513c5720f2a5bf197c26c02ea92debb012b0b6a6962c27a039a8ed309db05f2dccb14c3c543c543c4c3c432719a352a2c721dc2eea2db9b086b060a47729a82010a62e2fa8b0da2db6b0483c563c563c483cb11e19a3829cd726d22fa92de0b09eb012a1032b0618e6a89730b9b0502d4db13d3c5c3c5c3c3d3cffa34ba5911f0c2a5e30d62d15b1e9b0c39bec2b199f8ba9513182b0a12cf7b1363c613c613c363c512209a35fa22627b7304a2e84b106b191a5e92ba523c3a94d3177b14d2ea9b1313c623c623c313c29a6ada15a1f9d290f31c62c68b19ab06098692dd79d7eacc0320fb1102c52b2193c753c753c193ceea943a54226c82b2131712c55b188b00220fd2dd7a5a7ac35335bb0c928b4b2103c7c3c7c3c103cbba2a3a115a0292a6732262d97b20eb1f4a59c2d6128dfadc833e8b16c2cb9b2053c8e3c8e3c053cd3ac0220fc28472ab031ff20ecb15cad0c240e30009c55b069352eb190a671b3913bc63cc63c913b0faeaf1a832be72ae22f87a420b166a56f29493010a96eb093360db0e3aca2b44e3be63ce63c4e3be8284ea0dfa2c69e482d442d30b0ffafdba27a28e91654a31d2d16b01f2de0af543c533c533c543c442887a2fda11414e42d422d60b005b08fa6c4295a2258a62b2e69b0552d29b0553c4e3c4e3c553cd59801a3cc15cf26c82f302e24b193b003a6282b299ef4a5ab30e7b0a32d4fb1413c5e3c5e3c413c4a27f8a219a25a21f62ee22db9b08db00ea57c293d21c5a50e2fb1b0d12d99b0483c563c563c483cbe1f16a1d39d9f252330862de9b0b7b049a5012bb11ba5a75b30d5b05e2df1b03b3c5e3c5e3c3b3c0aa478a1730a6829b9308d2d07b122b148a4e32bb19c3ea80b31d5b00d2d73b1323c623c623c323c15228ca2f8a1d426f930232e99b11cb118a8172caf2436a92c3190b1272e5ab12d3c653c653c2d3c66a5a69c9618ba289a31af2c7ab1f1b07ea6502d9610bcaa3f325db1652c95b1153c763c763c153c36a9099e7421642aab31732c55b1eab04fa49b2d47a466aa7032feb0602bb6b10c3c7b3c7b3c0c3c28a3499f479e8e29f3326a2cb4b210b115abfe2d962a6aad923373b2232cccb1f83b953c953cf83b84ac38236f262e2ab5326024f9b170af20a6842f0d24e3aea034d8b1491afeb1aa3bb53cb53caa3b3fae3f226428492c0832502442b1f8ae2e22d92e74a8c3ad373509b1cea066b3793bc83cc83c793be728e1a251a0b49e1a2d1f2d16b0deaf5ca37b280e17daa2462d30b0442dfdaf543c533c533c543c4f281ba2a3a22c14332e512d6bb029b090a6e529e022e0a6e82d61b03f2d03b0563c4d3c4d3c563c4799bc15faa2d926ab30a42de6b04fb1f5a5212b489ef7a5cd2f23b12f2e95b0413c5e3c5e3c413c4a2719a2f8a25a210e2fd12db1b099b0c5a57c293c210ea5f62eb9b0e22d8db0483c563c563c483cbf1fd49d16a19f255b305e2dd5b0f1b0a5a7012bb41b49a52330e9b0862db7b03b3c5e3c5e3c3b3c0aa4630a78a168290b310d2dd5b073b13ea8e32bb09c48a4b93007b18d2d22b1323c623c623c323c1522f8a18ca2d4262c31272e90b15ab136a9172caf2418a8f93099b1232e1cb12d3c653c653c2d3c66a59618a69cba283f32652c5db195b1bcaa502d96107ea69a317ab1af2cf1b0153c763c763c153c36a97421099e642a7032602bfeb0b6b166aa9b2d47a44fa4ab3155b1732ceab00c3c7b3c7b3c0c3c28a3479e499f8e299233232c73b2ccb16aadfe2d962a15abf332b4b26a2c10b1f83b953c953cf83b84ac6f2638232e2aa034491ad8b1feb1e3ae842f0d2420a6b532f9b1602470afaa3bb53cb53caa3b3fae64283f22492c3835cea009b166b3c3add92e74a82d22083242b15024f8ae793bc83cc83c793b9228a1a157a17b9c402d1d2d19b0fbafeda27a287514d6a2152d17b0222dddaf543c533c533c543c81278aa0b8a2c41af52ea22d81b0a1b0dfa659291b1ccca1402d50b05b2db0af513c523c523c513c5720bf19f2a57c26ed305f2d9db0ccb139a8962c27a0b6a6c02eebb0a92d12b04c3c543c543c4c3c432752a219a3c7212e2fda2da8b0b6b010a67729a82060a4dc2eb9b0ea2d86b0483c563c563c483cb11e829c19a3d7269730502db9b04db1e6a8032b061812a1d22fe0b0a92d9eb03d3c5c3c5c3c3d3cffa3911f4ba50c2a5131a12c82b0f7b18ba9eb2b199fc39b5e3015b1d62de9b0363c613c613c363c51225fa209a326274d314d2e77b1a9b1c3a9e92ba52391a5b73084b14a2e06b1313c623c623c313c29a65a1fada19d29c032102c0fb152b27eac692dd69d60980f3168b1c62c9ab0193c753c753c193ceea9422643a5c82b3533c9285bb0b4b2a7acfd2dd7a50220213155b1712c88b0103c7c3c7c3c103cbba215a0a3a1292ac8336c2ce8b1b9b2dfad9c2d6128f4a5673297b2262d0eb1053c8e3c8e3c053cd3acfc280220472a693590a62eb171b355b00e30009c0c24b031ecb1ff205cad913bc63cc63c913b0fae832baf1ae72a9336e3ac0db0a2b46eb0493010a96f29e22f20b187a466a54e3be63ce63c4e3b8328d2a148a17f9b522d2c2d16b011b0ffa270282890c4a1092d0bb00c2dd4af533c543c543c533c3527b5a0c1a24a1ddb2ea32d6eb0adb03aa716292489549a402d50b0892de1af503c533c533c503cac227798e5a5a8260631452d73b00cb221aa172c299bb19d092e9db0532dc7af4b3c553c553c4b3c5e27b8a269a339224d2ff42da8b0d2b076a6672926201fa3a92eabb0fb2d84b04a3c543c543c4a3c0d1f039d3aa4ab27b030652d9fb095b135a9e52aef8cdf9a732fcbb0cd2d9bb0403c593c593c403c8ea20621cfa6492a7431152c1bb052b23aaa022ccca0c31c0330e7b0ba2db7b03a3c5e3c5e3c3a3cd923c6a300a304275831a42e6db1ebb116aaa42b6b215aa2683060b1722ef3b0353c5e3c5e3c353c98a5e11e17a4182ae832172cbfb0dab2f0ac672d82a2b622923036b1e32c6fb0213c6f3c6f3c213c0faa4e2851a85f2cbc33182520af98b37bad3b2e94a75f26903030b1672c32b0193c783c783c193ca7a033a17fa2182a9b33dd2c8fb120b3ecad662d7a243494bf3156b2c72d06b1123c823c823c123c36ac0b2936984f2a8435c6a818b02fb44eb014303fa6a9283331ccb1b62220ad983bc53cc53c983bc3adb72ced155829273783b0b1ac20b53fb11531a9aa932b6b2eb2b02dac7626353bfa3cfa3c353b662876a19ea1b6996c2d302d1eb019b058a39928019834a1f42c09b0172dd0af533c543c543c533c6b27aaa127a23d1de82ec22d76b0c0b070a761298f9cc50cf12c2bb0612db4af503c533c533c503c7021c91c89a63826bc305e2d33b00fb27da9d22b04a52721c52d86b0782de3af4a3c553c553c4a3c922791a31aa34622542f242eafb0e6b07da66a29a81e21a2862ea1b00a2e84b04b3c533c533c4b3c4c210b9f75a47727a330982d93b0b2b154a98b2a0304e314032fbfb0ed2d86b0433c563c563c433c19a0ab210fa82d2a6c31d72baeaf85b2a1aa152ccea23b224f2fc7b0ce2d8db03f3c5a3c5a3c3f3c0f25d4a479a274263c310c2f67b109b22eaa2e2b7b20269e1e303ab1922ee1b03b3c583c583c3b3cb7a20016a0a4da29c432772c85b021b3e3ac072dd4a3a025133002b1352d5bb02b3c663c663c2b3cc8a9d828a9a9b32cfb33a51e7dad25b40aae722e19a959290130e7b06b2c08b0243c6f3c6f3c243c689740a3cba173295933862d64b160b301ae522dba16a824133102b2392ef1b0203c743c743c203c60aadb275aa1572a443583a805ae7fb450b01430f2a9bf2b9d3082b1d9269fadc33bb13cb13cc33b49aec62d9da4402b313791b1159eb6b53eb1483182acbe2c4a2fe2b028acc01e593bec3cec3c593b722859a24aa16d98732d5c2d1ab035b0e3a29328449baca0fc2cf2af0a2de9af543c523c523c543cd12724a425a06e1cb12ea92d5db0b3b0c6a581284c17509c322d2eb06d2d03b0503c533c533c503cfb21f59690a56926ae30ed2cd2af13b2c1aa922ba6a6ca27c42cf5af1f2da3af4c3c523c523c4c3c05286ba49fa2f5213d2f692ec2b0ebb044a627296f1fc6a1652e99b01d2e86b04d3c513c513c4d3c6c2473a2b6a364266530052ea6b09bb1f2a8d229da1956189e2ea8b0142e83b0473c533c533c473c1593b11edca794291531372c91af6ab275aaa32b91a22024bc2ea3b0e62d79b0453c543c543c453cc32669a6eea060250331ae2f81b106b2d7a9a82aa41f389abd2f13b1b12ed8b0413c533c533c413c101037a0dba3d82842326e2d9ab004b383ac7f2c73a35b26532fd1b09b2d63b0373c5c3c5c3c373c02a9bc2894aac72cd033aa1f94ac4eb46dae932e5caa512bdd2e9cb0b12cf8af333c623c623c333c4e212da6799f8628e132962e65b16db3bbad052d9f9f39278430a9b1be2effb0313c643c643c313c84a7b0236da2c029a53421a017ad86b414b09b2fb9abee2cf82f24b1d92aeeae0b3c893c893c0b3cfcaeea2e4cac4d2e0d37e2b12c2c7bb66db17131f2ae3c2f4a2ff6b0689fcdaac43bb63cb63cc43b7a2840a2c2a14596a02d982d3eb045b0a9a3aa28e69619a1112d06b00d2de5af533c533c533c533c3828dda45f9e9f19632efd2d80b095b089a57228ab11e59a172d0cb0472d03b0503c533c533c503c7826d0a46a9a7c20da2f3d2e8ab05db135a87828b58b2520302d25b0692de3af503c4f3c4f3c503c5a2840a5f8a16f21122fba2ed4b0eab0c4a5b7288e20b4a1562e8fb0332e92b04e3c503c503c4e3cae2633a52aa19524ee2ff42ef6b055b1e8a7c82831200d98692e97b0342e8ab04b3c503c503c4b3cca235ea08ca419273830882d58b0a8b124a9152a859b3821252e6eb0dd2d60b04a3c503c503c4a3c8e282fa8069f0b24a8303630a4b1e4b12fa9af296d21b49a472ff2b0f42edfb0473c4d3c4d3c473cdf2543a7309844252c31972f46b155b2c1aa5e2a6294ef23a42ea1b0142e7eb0443c4f3c4f3c443ce59d051eaca7142a2532132bc0ae5bb318ad0b2d45a8de29a52d35b0072df5af443c543c543c443c5328d9a9081a6025c9317f300eb2dab273ac742b391c82240f305eb1642f27b1423c533c533c423c3723d8a656211d2450326a2d64b028b34ead802c58a7902a422f08b1ef2d77b0373c5e3c5e3c373c9dacad2c3aad9b2e5e35bfad182799b599b15331ccaf3930a02d55b0052b98ae2a3c6d3c6d3c2a3caa28a9a319a1e696982da02d45b03eb040a27a284596c2a10d2de5af112d06b0533c533c533c533c722889a5e59aab11fd2d632e95b080b0dda43828a0195f9e472d03b0172d0cb0533c503c503c533c782835a82520ad8b3d2eda2f5db18ab0d0a478267c20699a692de3af302d25b04f3c503c503c4f3cb728c4a5b4a18e20ba2e122feab0d4b040a55a286f21f8a1332e92b0562e8fb0503c4e3c4e3c503cc828e8a70d983120f42eee2f55b1f6b033a5ae2695242aa1342e8ab0692e97b0503c4b3c4b3c503c152a24a93821859b882d3830a8b158b05ea0ca2319278ca4dd2d60b0252e6eb0503c4a3c4a3c503caf292fa9b49a6d213630a830e4b1a4b12fa88e280b24069ff42edfb0472ff2b04d3c473c473c4d3c5e2ac1aaef236294972f2c3155b246b143a7df2544253098142e7eb0a42ea1b04f3c443c443c4f3c0b2d18adde2945a8132b25325bb3c0ae051ee59d142aaca7072df5afa52d35b0543c443c443c543c742b73ac8224391c7f30c931dab20eb2d9a953286025081a642f27b10f305eb1533c423c423c533c802c4ead902a58a76a2d503228b364b0d8a637231d245621ef2d77b0422f08b15e3c373c373c5e3c533199b13930ccafbfad5e3599b51827ad2c9dac9b2e3aad052b98aea02d55b06d3c2a3c2a3c6d3c9328e3a2aca0449b5c2d732d35b01ab059a272286d984aa10a2de9affc2cf2af523c543c543c523c8128c6a5509c4c17a92db12eb3b05db024a4d1276e1c26a06d2d03b0322d2eb0533c503c503c533c922bc1aaca27a6a6ed2cae3013b2d2aff496fb21692690a51f2da3afc42cf5af523c4c3c4c3c523c272944a6c6a16f1f692e3d2febb0c2b06ba40528f5219fa21d2e86b0652e99b0513c4d3c4d3c513cd229f2a85618da19052e65309bb1a6b073a26c246426b6a3142e83b09e2ea8b0533c473c473c533ca32b75aa202491a2372c15316ab291afb11e16939429dca7e62d79b0bc2ea3b0543c453c453c543ca82ad7a9389aa41fae2f033106b281b169a6c3266025eea0b12ed8b0bd2f13b1533c413c413c533c7f2c83ac5b2673a36e2d423204b39ab037a01010d828dba39b2d63b0532fd1b05c3c373c373c5c3c932e6dae512b5caaaa1fd0334eb494acbc2802a9c72c93aab12cf8afdd2e9cb0623c333c333c623c052dbbad39279f9f962ee1326db365b12da64e218628799fbe2effb08430a9b1643c313c313c643c9b2f14b0ee2cb9ab21a0a53486b417adb02384a7c0296da2d92aeeaef82f24b1893c0b3c0b3c893c71316db13c2ff2aee2b10d377bb62c2cea2efcae4d2e4cac689fcdaa4a2ff6b0b63cc43bc43bb63c992858a334a10198302d6c2d19b01eb076a16628b6999ea1172dd0aff42c09b0543c533c533c543c612970a7c40c8f9cc22de82ec0b076b0aaa16b273d1d27a2612db4aff12c2bb0533c503c503c533cd22b7da9282104a55e2dbc300fb233b0c91c7021382689a6782de3afc52d86b0553c4a3c4a3c553c6a297da621a2a81e242e542fe6b0afb091a3922746221aa30a2e84b0862ea1b0533c4b3c4b3c533c8b2a54a9e3140004982da330b2b193b00b9f4c21772775a4ed2d86b0032fbfb0563c433c433c563c152ca1aa3b22cea2d72b6c3185b2aeafab2119a02d2a0fa8ce2d8db04f2fc7b05a3c3f3c3f3c5a3c2e2b2eaa269e7b200c2f3c3109b267b1d4a40f25742679a2922ee1b01e303ab1583c3b3c3b3c583c072de3aca025d4a3772cc43221b385b00016b7a2da29a0a4352d5bb0133003b1663c2b3c2b3c663c722e0aae592919a9a51efb3325b47dadd828c8a9b32ca9a96b2c08b00130e7b06f3c243c243c6f3c522d01aea824b916862d593360b364b141a368977329cba1392ef1b0133102b2743c203c203c743c143050b0bf2bf2a983a844357fb405aedb2760aa572a5aa1d9269fad9d3082b1b13cc33bc33bb13c48313eb1be2c82ac91b13137b6b5159ec62d49ae402b9da428acc01e4a2fe2b0ec3c593b593bec3c7028ffa2c4a129902c2d522d11b016b0d2a183287f9b48a10c2dd4af092d0bb0543c533c533c543c16293aa7549a2489a32ddb2eadb06eb0b5a035274a1dc1a2892de1af402d50b0533c503c503c533c172c21aab19d299b452d06310cb273b07798ac22a826e5a5532dc7af092e9db0553c4b3c4b3c553c672976a61fa32620f42d4d2fd2b0a8b0b8a25e27392269a3fb2d84b0a92eabb0543c4a3c4a3c543ce52a35a9de9aec8c652db03095b19fb0039d0d1fab273aa4cd2d9bb0732fcbb0593c403c403c593c022c3aaac31ccca0152c743152b21bb006218ea2492acfa6ba2db7b00330e7b05e3c3a3c3a3c5e3ca42b16aa5aa26b21a42e5831ebb16db1c6a3d923042700a3722ef3b0683060b15e3c353c353c5e3c672df0acb62282a2172ce832dab2bfb0e11e98a5182a17a4e32c6fb0923036b16f3c213c213c6f3c3b2e7bad5f2694a71825bc3398b320af4e280faa5f2c51a8672c32b0903030b1783c193c193c783c662decad33947a24dd2c9b3320b38fb133a1a7a0182a7fa2c72d06b1bf3156b2823c123c123c823c14304eb0a9283fa6c6a884352fb418b00b2936ac4f2a3698b62220ad3331ccb1c53c983b983bc53c15313fb1932ba9aa83b0273720b5b1acb72cc3ad5829ed152dac76266b2eb2b0fa3c353b353bfa3c7a28eea2d6a275141d2d402dfbaf19b0a1a192287b9c57a1222dddaf152d17b0533c543c543c533c5929dfa6cca11b1ca22df52ea1b081b08aa08127c31ab8a25b2db0af402d50b0523c513c513c523c962c39a8b6a627a05f2ded30ccb19db0bf1957207c26f2a5a92d12b0c02eebb0543c4c3c4c3c543c772910a660a4a820da2d2e2fb6b0a8b052a24327c72119a3ea2d86b0dc2eb9b0563c483c483c563c032be6a812a10618502d97304db1b9b0829cb11ed72619a3a92d9eb0d22fe0b05c3c3d3c3d3c5c3cec2b8ba9c39b199fa12c5131f7b182b0911fffa30c2a4ba5d62de9b05e3015b1613c363c363c613ce92bc3a991a5a5234d2e4d31a9b177b15fa25122262709a34a2e06b1b73084b1623c313c313c623c692d7eac6098d79d102cc03252b20fb15a1f29a69d29ada1c62c9ab00f3168b1753c193c193c753cfd2da7ac0220d7a5c9283533b4b25bb04226eea9c82b43a5712c88b0213155b17c3c103c103c7c3c9c2ddfadf4a561286c2cc833b9b2e8b115a0bba2292aa3a1262d0eb1673297b28e3c053c053c8e3c0e3055b00c24009c90a6693571b32eb1fc28d3ac472a0220ff205cadb031ecb1c63c913b913bc63c49306eb06f2910a9e3ac9336a2b40db0832b0faee72aaf1a87a466a5e22f20b1e63c4e3b4e3be63c7a2854a3dba2e9161f2d1d2de0af16b0dfa2e828c69e4ea0442dffaf482d30b0533c543c543c533cc42958a68fa65a22552d2b2e29b069b0fda14428141487a2422d05b0e42d60b04e3c553c553c4e3c282bf4a504a6299ea32dab304fb1e7b0cc15d598cf2601a3302e93b0c82f24b15e3c413c413c5e3c7c29c5a50ea53d21d12d0e2f99b0b1b019a24a275a21f8a2e22d8db0f62eb9b0563c483c483c563c012ba5a749a5b11b5e2d5b30f1b0d5b0d39dbe1f9f2516a1862db7b02330e9b05e3c3b3c3b3c5e3ce32b3ea848a4b19c0d2d0b3173b1d5b0730a0aa4682978a18d2d22b1b93007b1623c323c323c623c172c36a918a8af24272e2c315ab190b1f8a11522d4268ca2232e1cb1f93099b1653c2d3c2d3c653c502dbcaa7ea69610652c3f3295b15db1961866a5ba28a69caf2cf1b09a317ab1763c153c153c763c9b2d66aa4fa447a4602b7032b6b1feb0742136a9642a099e732ceab0ab3155b17b3c0c3c0c3c7b3cfe2d6aad15ab962a232c9233ccb173b2479e28a38e29499f6a2c10b1f332b4b2953cf83bf83b953c842fe3ae20a60d24491aa034feb1d8b16f2684ac2e2a3823602470afb532f9b1b53caa3baa3bb53cd92ec3ad2e2274a8cea0373566b309b164283fae492c3f225024f8ae083242b1c83c793b793bc83c7b28daa25ca30e17442d462dfdaf30b051a0e728b59ee1a21f2ddeaf1a2d16b0533c543c543c533ce529e0a690a6e0223f2de82d03b061b0a3a24f282c141ba2512d29b0332e6bb04d3c563c563c4d3c212bf7a5f6a5489e2f2ecd2f95b023b1faa24799d926bc15a42d4fb1ab30e6b05e3c413c413c5e3c7c290ea5c5a53c21e22df62e8db0b9b0f8a24a275a2119a2d12d99b00e2fb1b0563c483c483c563c012b49a5a5a7b41b862d2330b7b0e9b016a1bf1f9f25d49d5e2df1b05b30d5b05e3c3b3c3b3c5e3ce32b48a43ea8b09c8d2db93022b107b178a10aa46829630a0d2d73b10b31d5b0623c323c323c623c172c18a836a9af24232ef9301cb199b18ca21522d426f8a1272e5ab12c3190b1653c2d3c2d3c653c502d7ea6bcaa9610af2c9a31f1b07ab1a69c66a5ba289618652c95b13f325db1763c153c153c763c9b2d4fa466aa47a4732cab31eab055b1099e36a9642a7421602bb6b17032feb07b3c0c3c0c3c7b3cfe2d15ab6aad962a6a2cf33210b1b4b2499f28a38e29479e232cccb1923373b2953cf83bf83b953c842f20a6e3ae0d246024b53270aff9b1382384ac2e2a6f26491afeb1a034d8b1b53caa3baa3bb53cd92e2d22c3ad74a850240832f8ae42b13f223fae492c6428cea066b3383509b1c83c793b793bc83c7a28d6a2eda27514222d152dddaf17b057a192287b9ca1a11d2dfbaf402d19b0533c543c543c533c5929cca1dfa61b1c5b2d402db0af50b0b8a28127c41a8aa0a22da1b0f52e81b0523c513c513c523c962cb6a639a827a0a92dc02e12b0ebb0f2a557207c26bf195f2dccb1ed309db0543c4c3c4c3c543c772960a410a6a820ea2ddc2e86b0b9b019a34327c72152a2da2db6b02e2fa8b0563c483c483c563c032b12a1e6a80618a92dd22f9eb0e0b019a3b11ed726829c502d4db19730b9b05c3c3d3c3d3c5c3ceb2bc39b8ba9199fd62d5e30e9b015b14ba5ffa30c2a911fa12cf7b1513182b0613c363c363c613ce92b91a5c3a9a5234a2eb73006b184b109a3512226275fa24d2ea9b14d3177b1623c313c313c623c692d60987eacd69dc62c0f319ab068b1ada129a69d295a1f102c52b2c0320fb1753c193c193c753cfd2d0220a7acd7a5712c213188b055b143a5eea9c82b4226c928b4b235335bb07c3c103c103c7c3c9c2df4a5dfad6128262d67320eb197b2a3a1bba2292a15a06c2cb9b2c833e8b18e3c053c053c8e3c0e300c2455b0009cff20b0315cadecb10220d3ac472afc2890a671b369352eb1c63c913b913bc63c49306f296eb010a987a4e22f66a520b1af1a0faee72a832be3aca2b493360db0e63c4e3b4e3be63c7028c4a1ffa228900c2d092dd4af0bb048a183287f9bd2a12c2d11b0522d16b0543c533c533c543c1629549a3aa72489892d402de1af50b0c1a235274a1db5a0a32dadb0db2e6eb0533c503c503c533c172cb29d21aa299b532d092ec7af9db0e5a5ac22a8267798452d0cb2063173b0553c4b3c4b3c553c67291fa376a62620fb2da92e84b0abb069a35e273922b8a2f42dd2b04d2fa8b0543c4a3c4a3c543ce52adf9a35a9ef8ccd2d732f9bb0cbb03aa40d1fab27039d652d95b1b0309fb0593c403c403c593c022cc31c3aaacca0ba2d0330b7b0e7b0cfa68ea2492a0621152c52b274311bb05e3c3a3c3a3c5e3ca42b5aa216aa6b21722e6830f3b060b100a3d9230427c6a3a42eebb158316db15e3c353c353c5e3c672db622f0ac82a2e32c92306fb036b117a498a5182ae11e172cdab2e832bfb06f3c213c213c6f3c3b2e5f267bad94a7672c903032b030b151a80faa5f2c4e28182598b3bc3320af783c193c193c783c662d3494ecad7a24c72dbf3106b156b27fa2a7a0182a33a1dd2c20b39b338fb1823c123c123c823c1430a9284eb03fa6b622333120adccb1369836ac4f2a0b29c6a82fb4843518b0c53c983b983bc53c1531932b3fb1a9aa2dac6b2e7626b2b0ed15c3ad5829b72c83b020b52737b1acfa3c353b353bfa3c992834a158a30198172df42cd0af09b09ea16628b69976a1302d19b06c2d1eb0543c533c533c543c6129c50c70a78f9c612df12cb4af2bb027a26b273d1daaa1c22dc0b0e82e76b0533c503c503c533cd22b27217da904a5782dc52de3af86b089a670213826c91c5e2d0fb2bc3033b0553c4a3c4a3c553c6a2921a27da6a81e0a2e862e84b0a1b01aa39227462291a3242ee6b0542fafb0533c4b3c4b3c533c8b2ae31454a90304ed2d032f86b0bfb075a44c2177270b9f982db2b1a33093b0563c433c433c563c152c3b22a1aacea2ce2d4f2f8db0c7b00fa819a02d2aab21d72b85b26c31aeaf5a3c3f3c3f3c5a3c2e2b269e2eaa7b20922e1e30e1b03ab179a20f257426d4a40c2f09b23c3167b1583c3b3c3b3c583c072da025e3acd4a3352d13305bb002b1a0a4b7a2da290016772c21b3c43285b0663c2b3c2b3c663c722e59290aae19a96b2c013008b0e7b0a9a9c8a9b32cd828a51e25b4fb337dad6f3c243c243c6f3c522da82401aeba16392e1331f1b002b2cba16897732940a3862d60b3593364b1743c203c203c743c1430bf2b50b0f2a9d9269d309fad82b15aa160aa572adb2783a87fb4443505aeb13cc33bc33bb13c4831be2c3eb182ac28ac4a2fc01ee2b09da449ae402bc62d91b1b6b53137159eec3c593b593bec3c9328aca0e3a2449b0a2dfc2ce9aff2af4aa172286d9859a25c2d35b0732d1ab0523c543c543c523c8128509cc6a54c176d2d322d03b02eb025a0d1276e1c24a4a92db3b0b12e5db0533c503c503c533c922bca27c1aaa6a61f2dc42ca3aff5af90a5fb216926f596ed2c13b2ae30d2af523c4c3c4c3c523c2729c6a144a66f1f1d2e652e86b099b09fa20528f5216ba4692eebb03d2fc2b0513c4d3c4d3c513cd2295618f2a8da19142e9e2e83b0a8b0b6a36c24642673a2052e9bb16530a6b0533c473c473c533ca32b202475aa91a2e62dbc2e79b0a3b0dca715939429b11e372c6ab2153191af543c453c453c543ca82a389ad7a9a41fb12ebd2fd8b013b1eea0c326602569a6ae2f06b2033181b1533c413c413c533c7f2c5b2683ac73a39b2d532f63b0d1b0dba31010d82837a06e2d04b342329ab05c3c373c373c5c3c932e512b6dae5caab12cdd2ef8af9cb094aa02a9c72cbc28aa1f4eb4d03394ac623c333c333c623c052d3927bbad9f9fbe2e8430ffb0a9b1799f4e2186282da6962e6db3e13265b1643c313c313c643c9b2fee2c14b0b9abd92af82feeae24b16da284a7c029b02321a086b4a53417ad893c0b3c0b3c893c71313c2f6db1f2ae689f4a2fcdaaf6b04cacfcae4d2eea2ee2b17bb60d372c2cb63cc43bc43bb63caa2819a1a9a3e6960d2d112de5af06b0c2a17a28459640a2982d45b0a02d3eb0533c533c533c533c7228e59a89a5ab11472d172d03b00cb05f9e38289f19dda4fd2d95b0632e80b0533c503c503c533c7828252035a8b58b692d302de3af25b06a9a78267c20d0a43d2e5db1da2f8ab04f3c503c503c4f3cb728b4a1c4a58e20332e562e92b08fb0f8a15a286f2140a5ba2eeab0122fd4b0503c4e3c4e3c503cc8280d98e8a73120342e692e8ab097b02aa1ae26952433a5f42e55b1ee2ff6b0503c4b3c4b3c503c152a382124a9859bdd2d252e60b06eb08ca4ca2319275ea0882da8b1383058b0503c4a3c4a3c503caf29b49a2fa96d21f42e472fdfb0f2b0069f8e280b242fa83630e4b1a830a4b14d3c473c473c4d3c5e2aef23c1aa6294142ea42e7eb0a1b03098df25442543a7972f55b22c3146b14f3c443c443c4f3c0b2dde2918ad45a8072da52df5af35b0aca7e59d142a051e132b5bb32532c0ae543c443c443c543c742b822473ac391c642f0f3027b15eb1081a53286025d9a97f30dab2c9310eb2533c423c423c533c802c902a4ead58a7ef2d422f77b008b1562137231d24d8a66a2d28b3503264b05e3c373c373c5e3c5331393099b1ccaf052ba02d98ae55b03aad9dac9b2ead2cbfad99b55e3518276d3c2a3c2a3c6d3c
